/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, Hardware
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <gtest/gtest.h>

#include "command/rs_canvas_node_command.h"
#include "command/rs_node_command.h"
#include "command/rs_root_node_command.h"
#include "common/rs_common_def.h"
#include "modifier/rs_modifier_type.h"
#include "platform/ohos/rs_modifiers_draw.h"
#include "transaction/rs_transaction_data.h"

using namespace testing;
using namespace testing::ext;

namespace OHOS {
namespace Rosen {
class RSModifiersDrawTest : public testing::Test {
public:
    static void SetUpTestCase();
    static void TearDownTestCase();
    void SetUp() override;
    void TearDown() override;
};

void RSModifiersDrawTest::SetUpTestCase() {}
void RSModifiersDrawTest::TearDownTestCase() {}
void RSModifiersDrawTest::SetUp() {}
void RSModifiersDrawTest::TearDown() {}

/**
 * @tc.name: DmaMemAllocTest001
 * @tc.desc: test results of DmaMemAlloc
 * @tc.type:FUNC
 * @tc.require:
 */
HWTEST_F(RSModifiersDrawTest, DmaMemAllocTest001, TestSize.Level1)
{
    auto pixelMap = std::make_unique<Media::PixelMap>();
    int32_t width = 100;
    int32_t height = 100;
    auto result = RSModifiersDraw::DmaMemAlloc(width, height, pixelMap);
    ASSERT_NE(result, nullptr);
}

/**
 * @tc.name: DmaMemAllocTest002
 * @tc.desc: test results of DmaMemAlloc
 * @tc.type:FUNC
 * @tc.require:
 */
HWTEST_F(RSModifiersDrawTest, DmaMemAllocTest002, TestSize.Level1)
{
    auto pixelMap = std::make_unique<Media::PixelMap>();
    int32_t width = 0;
    int32_t height = 0;
    auto result = RSModifiersDraw::DmaMemAlloc(width, height, pixelMap);
    ASSERT_EQ(result, nullptr);
}

/**
 * @tc.name: CreateSurfaceFromGpuContextTest001
 * @tc.desc: test results of CreateSurfaceFromGpuContext
 * @tc.type:FUNC
 * @tc.require:
 */
HWTEST_F(RSModifiersDrawTest, CreateSurfaceFromGpuContextTest001, TestSize.Level1)
{
    auto pixelMap = std::make_unique<Media::PixelMap>();
    int32_t width = 100;
    int32_t height = 100;
    auto result = RSModifiersDraw::CreateSurfaceFromGpuContext(pixelMap, width, height);
    ASSERT_NE(result, nullptr);
}

/**
 * @tc.name: CreateSurfaceFromGpuContextTest002
 * @tc.desc: test results of CreateSurfaceFromGpuContext
 * @tc.type:FUNC
 * @tc.require:
 */
HWTEST_F(RSModifiersDrawTest, CreateSurfaceFromGpuContextTest002, TestSize.Level1)
{
    auto pixelMap = std::make_unique<Media::PixelMap>();
    int32_t width = 0;
    int32_t height = 0;
    auto result = RSModifiersDraw::CreateSurfaceFromGpuContext(pixelMap, width, height);
    ASSERT_EQ(result, nullptr);
}

/**
 * @tc.name: CreateSurfaceFromCpuContextTest001
 * @tc.desc: test results of CreateSurfaceFromCpuContext
 * @tc.type:FUNC
 * @tc.require:
 */
HWTEST_F(RSModifiersDrawTest, CreateSurfaceFromCpuContextTest001, TestSize.Level1)
{
    int32_t width = 100;
    int32_t height = 100;
    auto pixelMap = RSModifiersDraw::CreatePixelMap(width, height);
    auto result = RSModifiersDraw::CreateSurfaceFromCpuContext(pixelMap);
    ASSERT_NE(result, nullptr);
}

/**
 * @tc.name: CreateSurfaceFromCpuContextTest002
 * @tc.desc: test results of CreateSurfaceFromCpuContext
 * @tc.type:FUNC
 * @tc.require:
 */
HWTEST_F(RSModifiersDrawTest, CreateSurfaceFromCpuContextTest002, TestSize.Level1)
{
    auto pixelMap = std::make_unique<Media::PixelMap>();
    auto result = RSModifiersDraw::CreateSurfaceFromCpuContext(pixelMap);
    ASSERT_EQ(result, nullptr);
}

/**
 * @tc.name: CreateSurfaceTest001
 * @tc.desc: test results of CreateSurface
 * @tc.type:FUNC
 * @tc.require:
 */
HWTEST_F(RSModifiersDrawTest, CreateSurfaceTest001, TestSize.Level1)
{
    auto pixelMap = std::make_unique<Media::PixelMap>();
    int32_t width = 100;
    int32_t height = 100;
    auto result = RSModifiersDraw::CreateSurface(pixelMap, width, height);
    ASSERT_NE(result, nullptr);
}

/**
 * @tc.name: CreateSurfaceTest002
 * @tc.desc: test results of CreateSurface
 * @tc.type:FUNC
 * @tc.require:
 */
HWTEST_F(RSModifiersDrawTest, CreateSurfaceTest002, TestSize.Level1)
{
    auto pixelMap = std::make_unique<Media::PixelMap>();
    int32_t width = 0;
    int32_t height = 0;
    auto result = RSModifiersDraw::CreateSurface(pixelMap, width, height);
    ASSERT_EQ(result, nullptr);
}

/**
 * @tc.name: PlaybackTest
 * @tc.desc: test results of Playback
 * @tc.type:FUNC
 * @tc.require:
 */
HWTEST_F(RSModifiersDrawTest, PlaybackTest, TestSize.Level1)
{
    NodeId nodeId = 1;
    int32_t width = 100;
    int32_t height = 100;
    RSModifiersDraw::ResetSurfaceByNodeId(width, height, nodeId, false);
    auto surfaceAndPixelMap = RSModifiersDraw::GetSurfaceAndPixelMapByNodeId(nodeId);
    auto surface = surfaceAndPixelMap.first;
    auto cmdList = std::make_shared<Drawing::DrawCmdList>();
    bool isCanvasType = true;
    RSModifiersDraw::Playback(surface, cmdList, isCanvasType);
    RSModifiersDraw::RemoveSurfaceByNodeId(nodeId, false);
    auto surfaceAndPixelMap2 = RSModifiersDraw::GetSurfaceAndPixelMapByNodeId(nodeId);
    ASSERT_EQ(surfaceAndPixelMap2.first, nullptr);
    ASSERT_EQ(surfaceAndPixelMap2.second, nullptr);
}

/**
 * @tc.name: AddPixelMapDrawOpTest
 * @tc.desc: test results of AddPixelMapDrawOp
 * @tc.type:FUNC
 * @tc.require:
 */
HWTEST_F(RSModifiersDrawTest, AddPixelMapDrawOpTest, TestSize.Level1)
{
    auto cmdList = std::make_shared<Drawing::DrawCmdList>();
    auto pixelMap = std::make_shared<Media::PixelMap>();
    int32_t width = 100;
    int32_t height = 100;
    RSModifiersDraw::AddPixelMapDrawOp(cmdList, pixelMap, width, height);
    ASSERT_NE(cmdList, nullptr);
}

/**
 * @tc.name: InvalidateSurfaceCacheTest001
 * @tc.desc: test results of InvalidateSurfaceCache
 * @tc.type:FUNC
 * @tc.require:
 */
HWTEST_F(RSModifiersDrawTest, InvalidateSurfaceCacheTest001, TestSize.Level1)
{
    auto pixelMap = std::make_shared<Media::PixelMap>();
    RSModifiersDraw::InvalidateSurfaceCache(pixelMap);
    ASSERT_NE(pixelMap, nullptr);
}

/**
 * @tc.name: InvalidateSurfaceCacheTest002
 * @tc.desc: test results of InvalidateSurfaceCache
 * @tc.type:FUNC
 * @tc.require:
 */
HWTEST_F(RSModifiersDrawTest, InvalidateSurfaceCacheTest002, TestSize.Level1)
{
    std::shared_ptr<Media::PixelMap> pixelMap = nullptr;
    RSModifiersDraw::InvalidateSurfaceCache(pixelMap);
    ASSERT_EQ(pixelMap, nullptr);
}

/**
 * @tc.name: ConvertCmdListForCanvasTest
 * @tc.desc: test results of ConvertCmdListForCanvas
 * @tc.type:FUNC
 * @tc.require:
 */
HWTEST_F(RSModifiersDrawTest, ConvertCmdListForCanvasTest, TestSize.Level1)
{
    NodeId nodeId = 1;
    int32_t width = 100;
    int32_t height = 100;
    auto cmdList = std::make_shared<Drawing::DrawCmdList>(width, height);
    RSModifiersDraw::ConvertCmdListForCanvas(cmdList, nodeId);
    ASSERT_NE(cmdList, nullptr);
}

/**
 * @tc.name: ConvertCmdListTest
 * @tc.desc: test results of ConvertCmdList
 * @tc.type:FUNC
 * @tc.require:
 */
HWTEST_F(RSModifiersDrawTest, ConvertCmdListTest, TestSize.Level1)
{
    int32_t width = 100;
    int32_t height = 100;
    auto cmdList = std::make_shared<Drawing::DrawCmdList>(width, height);
    RSModifiersDraw::ConvertCmdList(cmdList);
    ASSERT_NE(cmdList, nullptr);
}

/**
 * @tc.name: TargetCommadTest001
 * @tc.desc: test results of TargetCommad
 * @tc.type:FUNC
 * @tc.require:
 */
HWTEST_F(RSModifiersDrawTest, TargetCommadTest001, TestSize.Level1)
{
    NodeId nodeId = 1;
    auto cmdList = std::make_shared<Drawing::DrawCmdList>();
    cmdList->SetHybridRenderType(Drawing::DrawCmdList::HybridRenderType::CANVAS);
    uint64_t propertyId = 1;
    auto type = PropertyUpdateType::UPDATE_TYPE_OVERWRITE;
    auto command = std::make_unique<RSUpdatePropertyDrawCmdList>(nodeId, cmdList, propertyId, type);
    ASSERT_TRUE(RSModifiersDraw::TargetCommad(std::move(command)));
}

/**
 * @tc.name: TargetCommadTest002
 * @tc.desc: test results of TargetCommad
 * @tc.type:FUNC
 * @tc.require:
 */
HWTEST_F(RSModifiersDrawTest, TargetCommadTest002, TestSize.Level1)
{
    NodeId nodeId = 1;
    auto cmdList = std::make_shared<Drawing::DrawCmdList>();
    cmdList->SetHybridRenderType(Drawing::DrawCmdList::HybridRenderType::CANVAS);
    auto type = RSModifierType::CONTENT_STYLE;
    auto command = std::make_unique<RSCanvasNodeUpdateRecording>(nodeId, cmdList, static_cast<uint16_t>(type));
    ASSERT_TRUE(RSModifiersDraw::TargetCommad(std::move(command)));
}

/**
 * @tc.name: TargetCommadTest003
 * @tc.desc: test results of TargetCommad
 * @tc.type:FUNC
 * @tc.require:
 */
HWTEST_F(RSModifiersDrawTest, TargetCommadTest003, TestSize.Level1)
{
    NodeId nodeId = 1;
    auto cmdList = std::make_shared<Drawing::DrawCmdList>();
    cmdList->SetHybridRenderType(Drawing::DrawCmdList::HybridRenderType::NONE);
    auto type = RSModifierType::CONTENT_STYLE;
    auto command = std::make_unique<RSCanvasNodeUpdateRecording>(nodeId, cmdList, static_cast<uint16_t>(type));
    ASSERT_FALSE(RSModifiersDraw::TargetCommad(std::move(command)));
}

/**
 * @tc.name: ConvertTransactionTest001
 * @tc.desc: test results of ConvertTransaction
 * @tc.type:FUNC
 * @tc.require:
 */
HWTEST_F(RSModifiersDrawTest, ConvertTransactionTest001, TestSize.Level1)
{
    NodeId nodeId = 1;
    auto type = RSModifierType::CONTENT_STYLE;
    auto cmdList = std::make_shared<Drawing::DrawCmdList>();
    cmdList->SetHybridRenderType(Drawing::DrawCmdList::HybridRenderType::CANVAS);
    auto command = std::make_unique<RSCanvasNodeUpdateRecording>(nodeId, cmdList, static_cast<uint16_t>(type));
    auto transactionData = std::make_unique<RSTransactionData>();
    transactionData->AddCommand(std::move(command), nodeId, FollowType::NONE);
    RSModifiersDraw::ConvertTransaction(transactionData);
    ASSERT_NE(transactionData, nullptr);
}

/**
 * @tc.name: ConvertTransactionTest002
 * @tc.desc: test results of ConvertTransaction
 * @tc.type:FUNC
 * @tc.require:
 */
HWTEST_F(RSModifiersDrawTest, ConvertTransactionTest002, TestSize.Level1)
{
    NodeId nodeId = 1;
    auto type = RSModifierType::CONTENT_STYLE;
    auto cmdList = std::make_shared<Drawing::DrawCmdList>();
    cmdList->SetHybridRenderType(Drawing::DrawCmdList::HybridRenderType::TEXT);
    auto command = std::make_unique<RSCanvasNodeUpdateRecording>(nodeId, cmdList, static_cast<uint16_t>(type));
    auto transactionData = std::make_unique<RSTransactionData>();
    transactionData->AddCommand(std::move(command), nodeId, FollowType::NONE);
    RSModifiersDraw::ConvertTransaction(transactionData);
    ASSERT_NE(transactionData, nullptr);
}

/**
 * @tc.name: ConvertTransactionTest003
 * @tc.desc: test results of ConvertTransaction
 * @tc.type:FUNC
 * @tc.require:
 */
HWTEST_F(RSModifiersDrawTest, ConvertTransactionTest003, TestSize.Level1)
{
    std::unique_ptr<RSTransactionData> transactionData = nullptr;
    RSModifiersDraw::ConvertTransaction(transactionData);
    ASSERT_EQ(transactionData, nullptr);
}

/**
 * @tc.name: CreatePixelMapTest001
 * @tc.desc: test results of CreatePixelMap
 * @tc.type:FUNC
 * @tc.require:
 */
HWTEST_F(RSModifiersDrawTest, CreatePixelMapTest001, TestSize.Level1)
{
    int32_t width = 100;
    int32_t height = 100;
    auto pixelMap = RSModifiersDraw::CreatePixelMap(width, height);
    ASSERT_NE(pixelMap, nullptr);
}

/**
 * @tc.name: CreatePixelMapTest002
 * @tc.desc: test results of CreatePixelMap
 * @tc.type:FUNC
 * @tc.require:
 */
HWTEST_F(RSModifiersDrawTest, CreatePixelMapTest002, TestSize.Level1)
{
    int32_t width = 0;
    int32_t height = 0;
    auto pixelMap = RSModifiersDraw::CreatePixelMap(width, height);
    ASSERT_EQ(pixelMap, nullptr);
}

/**
 * @tc.name: GetSurfaceAndPixelMapByNodeIdTest001
 * @tc.desc: test results of GetSurfaceAndPixelMapByNodeId
 * @tc.type:FUNC
 * @tc.require:
 */
HWTEST_F(RSModifiersDrawTest, GetSurfaceAndPixelMapByNodeIdTest001, TestSize.Level1)
{
    NodeId nodeId = 1;
    auto surface = std::make_shared<Drawing::Surface>();
    auto pixelMap = std::make_shared<Media::PixelMap>();
    RSModifiersDraw::surfaceMap_.emplace(nodeId, std::make_pair(surface, pixelMap));
    auto result = RSModifiersDraw::GetSurfaceAndPixelMapByNodeId(nodeId);
    ASSERT_NE(result.first, nullptr);
    ASSERT_NE(result.second, nullptr);
    RSModifiersDraw::RemoveSurfaceByNodeId(nodeId, false);
    auto result2 = RSModifiersDraw::GetSurfaceAndPixelMapByNodeId(nodeId);
    ASSERT_EQ(result2.first, nullptr);
    ASSERT_EQ(result2.second, nullptr);
}

/**
 * @tc.name: GetSurfaceAndPixelMapByNodeIdTest002
 * @tc.desc: test results of GetSurfaceAndPixelMapByNodeId
 * @tc.type:FUNC
 * @tc.require:
 */
HWTEST_F(RSModifiersDrawTest, GetSurfaceAndPixelMapByNodeIdTest002, TestSize.Level1)
{
    NodeId nodeId = 1;
    auto result = RSModifiersDraw::GetSurfaceAndPixelMapByNodeId(nodeId);
    ASSERT_EQ(result.first, nullptr);
    ASSERT_EQ(result.second, nullptr);
}

/**
 * @tc.name: GetPixelMapByNodeIdTest001
 * @tc.desc: test results of GetPixelMapByNodeId
 * @tc.type:FUNC
 * @tc.require:
 */
HWTEST_F(RSModifiersDrawTest, GetPixelMapByNodeIdTest001, TestSize.Level1)
{
    NodeId nodeId = 1;
    int32_t width = 100;
    int32_t height = 100;
    bool postTask = false;
    RSModifiersDraw::ResetSurfaceByNodeId(width, height, nodeId, postTask);
    auto result = RSModifiersDraw::GetPixelMapByNodeId(nodeId);
    ASSERT_NE(result, nullptr);
    RSModifiersDraw::RemoveSurfaceByNodeId(nodeId, false);
    auto result2 = RSModifiersDraw::GetPixelMapByNodeId(nodeId);
    ASSERT_EQ(result2, nullptr);
}

/**
 * @tc.name: GetPixelMapByNodeIdTest002
 * @tc.desc: test results of GetPixelMapByNodeId
 * @tc.type:FUNC
 * @tc.require:
 */
HWTEST_F(RSModifiersDrawTest, GetPixelMapByNodeIdTest002, TestSize.Level1)
{
    NodeId nodeId = 1;
    auto result = RSModifiersDraw::GetPixelMapByNodeId(nodeId);
    ASSERT_EQ(result, nullptr);
}

/**
 * @tc.name: RemoveSurfaceByNodeIdTest001
 * @tc.desc: test results of RemoveSurfaceByNodeId
 * @tc.type:FUNC
 * @tc.require:
 */
HWTEST_F(RSModifiersDrawTest, RemoveSurfaceByNodeIdTest001, TestSize.Level1)
{
    NodeId nodeId = 1;
    auto surface = std::make_shared<Drawing::Surface>();
    auto pixelMap = std::make_shared<Media::PixelMap>();
    RSModifiersDraw::surfaceMap_.emplace(nodeId, std::make_pair(surface, pixelMap));
    auto result = RSModifiersDraw::GetSurfaceAndPixelMapByNodeId(nodeId);
    ASSERT_NE(result.first, nullptr);
    bool postTask = false;
    RSModifiersDraw::RemoveSurfaceByNodeId(nodeId, postTask);
    auto result2 = RSModifiersDraw::GetSurfaceAndPixelMapByNodeId(nodeId);
    ASSERT_EQ(result2.first, nullptr);
}

/**
 * @tc.name: RemoveSurfaceByNodeIdTest002
 * @tc.desc: test results of RemoveSurfaceByNodeId
 * @tc.type:FUNC
 * @tc.require:
 */
HWTEST_F(RSModifiersDrawTest, RemoveSurfaceByNodeIdTest002, TestSize.Level1)
{
    NodeId nodeId = 1;
    auto surface = std::make_shared<Drawing::Surface>();
    auto pixelMap = std::make_shared<Media::PixelMap>();
    RSModifiersDraw::surfaceMap_.emplace(nodeId, std::make_pair(surface, pixelMap));
    auto result = RSModifiersDraw::GetSurfaceAndPixelMapByNodeId(nodeId);
    ASSERT_NE(result.first, nullptr);
    bool postTask = true;
    RSModifiersDraw::RemoveSurfaceByNodeId(nodeId, postTask);
    usleep(200 * 1000);
    result = RSModifiersDraw::GetSurfaceAndPixelMapByNodeId(nodeId);
    ASSERT_EQ(result.first, nullptr);
}

/**
 * @tc.name: ResetSurfaceByNodeIdTest001
 * @tc.desc: test results of ResetSurfaceByNodeId
 * @tc.type:FUNC
 * @tc.require:
 */
HWTEST_F(RSModifiersDrawTest, ResetSurfaceByNodeIdTest001, TestSize.Level1)
{
    NodeId nodeId = 1;
    int32_t width = 100;
    int32_t height = 100;
    bool postTask = false;
    ASSERT_TRUE(RSModifiersDraw::ResetSurfaceByNodeId(width, height, nodeId, postTask));
    auto result = RSModifiersDraw::GetSurfaceAndPixelMapByNodeId(nodeId);
    ASSERT_NE(result.first, nullptr);
    ASSERT_NE(result.second, nullptr);
    RSModifiersDraw::RemoveSurfaceByNodeId(nodeId, false);
    result = RSModifiersDraw::GetSurfaceAndPixelMapByNodeId(nodeId);
    ASSERT_EQ(result.first, nullptr);
    ASSERT_EQ(result.second, nullptr);
}

/**
 * @tc.name: ResetSurfaceByNodeIdTest002
 * @tc.desc: test results of ResetSurfaceByNodeId
 * @tc.type:FUNC
 * @tc.require:
 */
HWTEST_F(RSModifiersDrawTest, ResetSurfaceByNodeIdTest002, TestSize.Level1)
{
    NodeId nodeId = 1;
    int32_t width = 100;
    int32_t height = 100;
    bool postTask = true;
    auto result = RSModifiersDraw::ResetSurfaceByNodeId(width, height, nodeId, postTask);
    ASSERT_TRUE(result);
}

/**
 * @tc.name: ResetSurfaceByNodeIdTest003
 * @tc.desc: test results of ResetSurfaceByNodeId
 * @tc.type:FUNC
 * @tc.require:
 */
HWTEST_F(RSModifiersDrawTest, ResetSurfaceByNodeIdTest003, TestSize.Level1)
{
    NodeId nodeId = 1;
    int32_t width = 0;
    int32_t height = 0;
    bool postTask = false;
    ASSERT_FALSE(RSModifiersDraw::ResetSurfaceByNodeId(width, height, nodeId, postTask));
}
} // namespace Rosen
} // namespace OHOS